﻿using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Effects;

namespace Motar.Desktop.Controls.Effects
{

    /// <summary>
    /// 
    /// </summary>
    public class GrayscaleEffect : ShaderEffect
    {

        /// <summary>
        /// 
        /// </summary>
        private readonly static PixelShader DefaultPixelShader = new PixelShader() { UriSource = new Uri(@"pack://application:,,,/Motar.Desktop.Controls;component/src/Effects/GrayscaleEffect/GrayscaleEffect.ps") };

        /// <summary>
        /// 
        /// </summary>
        public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(GrayscaleEffect), 0);

        /// <summary>
        /// 
        /// </summary>
        public static readonly DependencyProperty DesaturationFactorProperty = DependencyProperty.Register("DesaturationFactor", typeof(double), typeof(GrayscaleEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(0), CoerceDesaturationFactor));

        /// <summary>
        /// 
        /// </summary>
        /// <param name="d"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        private static object CoerceDesaturationFactor(DependencyObject d, object value)
        {
            GrayscaleEffect effect = (GrayscaleEffect)d;

            double newFactor = (double)value;

            if (newFactor < 0.0 || newFactor > 1.0)
            {
                return effect.DesaturationFactor;
            }

            return newFactor;
        }

        /// <summary>
        /// 
        /// </summary>
        public GrayscaleEffect()
        {
            PixelShader = DefaultPixelShader;

            UpdateShaderValue(InputProperty);

            UpdateShaderValue(DesaturationFactorProperty);
        }

        /// <summary>
        /// 
        /// </summary>
        public Brush Input
        {
            get { return (Brush)GetValue(InputProperty); }
            set { SetValue(InputProperty, value); }
        }

        /// <summary>
        /// 
        /// </summary>
        public double DesaturationFactor
        {
            get { return (double)GetValue(DesaturationFactorProperty); }
            set { SetValue(DesaturationFactorProperty, value); }
        }
    }
}
